/**
 * 文件名：@MagicalParamHandlerInterceptor.java <br/>
 * 包名：cn.efunbox.afw.web.mvc.interceptor <br/>
 * 项目名：afw-web <br/>
 * @author xtwin <br/>
 */
package cn.efunbox.afw.web.mvc.interceptor;

import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.core.DefaultParameterNameDiscoverer;
import org.springframework.core.MethodParameter;
import org.springframework.core.ParameterNameDiscoverer;
import org.springframework.util.StringUtils;
import org.springframework.web.method.HandlerMethod;

import cn.efunbox.afw.core.annotation.mvc.MagicalParam;
import cn.efunbox.afw.web.util.AfwWebConstant;

/**
 * 类名：MagicalParamHandlerInterceptor  <br />
 *
 * 功能：参数解析
 *
 * @author xtwin <br />
 * 创建时间：2016年7月29日 下午3:11:28  <br />
 * @version 2016年7月29日
 */
public class MagicalParamHandlerInterceptor extends HandlerMethodMappingRequestBodyInterceptor {
	
	// 方法参数发现
	protected ParameterNameDiscoverer parameterNameDiscoverer = new DefaultParameterNameDiscoverer();

	/**
	 * 功能: <br/>
	 * 
	 * 重写：xtwin <br/>
	 * 
	 * @version ：2016年7月29日 下午3:11:45<br/>
	 * 
	 * @param request
	 * @param response
	 * @param handler
	 * @return
	 * @throws Exception <br/>
	 * @see org.springframework.web.servlet.handler.HandlerInterceptorAdapter#preHandle(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, java.lang.Object)
	 */
	@SuppressWarnings("unchecked")
	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
		if (! super.preHandle(request, response, handler)) {
			return false;
		}
		
		if (handler instanceof HandlerMethod) {
			MethodParameter[] parameters = ((HandlerMethod) handler).getMethodParameters();
			
			if (parameters.length == 0) {
				return true;
			}
			
			// 取出body
			Map<String, String> body = (Map<String, String>) request.getAttribute(AfwWebConstant.KEY_REQUEST_BODY);
			if (null == body) {
				body = new HashMap<>();
			}
			
			// 依次处理每个参数
			for (MethodParameter parameter : parameters) {
				// 检查参数上是否有注解
				MagicalParam magical = parameter.getParameterAnnotation(MagicalParam.class);
				if (null == magical) {
					// 忽略没有注解的参数
					continue;
				}
				
				// 参数名提取
				String name = magical.value();
				if (StringUtils.isEmpty(name)) {
					// 初始化方法名称发现器
					parameter.initParameterNameDiscovery(parameterNameDiscoverer);
					// 取得方法参数名
					name = parameter.getParameterName();
				}
				
				if (StringUtils.isEmpty(name)) {
					// 忽略找不到参数名的项
					continue;
				}
				
				if (! body.containsKey(name)) {
					// 以body参数为主，若body中没有定义，再使用该参数
					// 取得参数值
					String value = request.getParameter(name);
					if (StringUtils.isEmpty(value)) {
						continue;
					}
					
					// 保存该参数
					body.put(name, value);
				}
			}
			
			if (! body.isEmpty()) {
				request.setAttribute(AfwWebConstant.KEY_REQUEST_BODY, body);
			}
		}
		
		// 保存参数
		//request.setAttribute(AfwWebConstant.KEY_REQUEST_MAGICAL_PARAM, datas.isEmpty());
		
		return true;
	}

	/**
	 * @version 2016年7月29日-下午3:21:19
	 */
	public void setParameterNameDiscoverer(ParameterNameDiscoverer parameterNameDiscoverer) {
		this.parameterNameDiscoverer = parameterNameDiscoverer;
	}
}